package com.zhiche.wms.admin.controller.inbound;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.zhiche.wms.admin.vo.InboundOrderVo;
import com.zhiche.wms.core.supports.BaseException;
import com.zhiche.wms.core.supports.RestfulResponse;
import com.zhiche.wms.core.supports.enums.TableStatusEnum;
import com.zhiche.wms.domain.model.base.Storehouse;
import com.zhiche.wms.domain.model.inbound.InboundNoticeHeader;
import com.zhiche.wms.domain.model.inbound.InboundNoticeLine;
import com.zhiche.wms.service.base.IBusinessDocNumberService;
import com.zhiche.wms.service.base.IStorehouseService;
import com.zhiche.wms.service.constant.MeasureUnit;
import com.zhiche.wms.service.constant.Status;
import com.zhiche.wms.service.inbound.IInboundNoticeHeaderService;
import com.zhiche.wms.service.inbound.IInboundNoticeLineService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * Created by zhaoguixin on 2018/6/23.
 */
@RestController
@RequestMapping("/inbound/orderImport")
public class OrderImport {
    private static final Logger logger = LoggerFactory.getLogger(OrderImport.class);

    @Autowired
    private IInboundNoticeHeaderService inboundNoticeHeaderService;

    @Autowired
    private IInboundNoticeLineService inboundNoticeLineService;

    @Autowired
    private IStorehouseService storehouseService;

    @Autowired
    private IBusinessDocNumberService businessDocNumberService;

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

    private static Map<String, Storehouse> storehouseMap = new HashMap<>();

    /**
     * 更新
     */
    @PostMapping("/importData")
    public RestfulResponse<Map<String, JSONArray>> importData(@RequestBody String data) {
        logger.info("contoller:inbound/orderImport/importData data: {}", data);
        JSONObject jsonObject = JSONObject.parseObject(data);
        JSONArray arrayHeader = JSONObject.parseArray(jsonObject.getString("header"));
        if (!arrayHeader.get(arrayHeader.size() - 1).equals("备注")) {
            arrayHeader.add("导入结果");
            arrayHeader.add("备注");
        }

        JSONArray arrayRows = JSONObject.parseArray(jsonObject.getString("rows"));
        Map<String, JSONArray> map = new HashMap<>();
        for (int i = 0; i < arrayRows.size(); i++) {
            InboundOrderVo inboundOrderVo = new InboundOrderVo();
            inboundOrderVo.setCustomer(StringUtils.isBlank(arrayRows.getJSONObject(i).getString("客户")) ?
                    null : arrayRows.getJSONObject(i).getString("客户").trim());
            inboundOrderVo.setOwnerNo(StringUtils.isBlank(arrayRows.getJSONObject(i).getString("单号")) ?
                    null : arrayRows.getJSONObject(i).getString("单号").trim());
            inboundOrderVo.setStorehouseName(StringUtils.isBlank(arrayRows.getJSONObject(i).getString("收货仓库")) ?
                    null : arrayRows.getJSONObject(i).getString("收货仓库").trim());
            inboundOrderVo.setVehicleMode(StringUtils.isBlank(arrayRows.getJSONObject(i).getString("车系")) ?
                    null : arrayRows.getJSONObject(i).getString("车系").trim());
            inboundOrderVo.setVin(StringUtils.isBlank(arrayRows.getJSONObject(i).getString("序列号")) ?
                    null : arrayRows.getJSONObject(i).getString("序列号").trim());
            inboundOrderVo.setStrQty(StringUtils.isBlank(arrayRows.getJSONObject(i).getString("数量")) ?
                    null : arrayRows.getJSONObject(i).getString("数量").trim());
            inboundOrderVo.setCarrierName(StringUtils.isBlank(arrayRows.getJSONObject(i).getString("承运商")) ?
                    null : arrayRows.getJSONObject(i).getString("承运商").trim());
            inboundOrderVo.setExpectArriveDate(StringUtils.isBlank(arrayRows.getJSONObject(i).getString("预计到达日期")) ?
                    null : arrayRows.getJSONObject(i).getString("预计到达日期").trim());
            inboundOrderVo.setPlateNumber(StringUtils.isBlank(arrayRows.getJSONObject(i).getString("车船号")) ?
                    null : arrayRows.getJSONObject(i).getString("车船号").trim());
            inboundOrderVo.setDestLocationDetail(StringUtils.isBlank(arrayRows.getJSONObject(i).getString("目的地")) ?
                    null : arrayRows.getJSONObject(i).getString("目的地").trim());

            if (StringUtils.isEmpty(inboundOrderVo.getCustomer())) {
                arrayRows.getJSONObject(i).put("导入结果", "失败");
                arrayRows.getJSONObject(i).put("备注", "客户为空！");
                continue;
            }
            if (StringUtils.isEmpty(inboundOrderVo.getOwnerNo())) {
                arrayRows.getJSONObject(i).put("导入结果", "失败");
                arrayRows.getJSONObject(i).put("备注", "单号为空！");
                continue;
            }
            if (StringUtils.isEmpty(inboundOrderVo.getStorehouseName())) {
                arrayRows.getJSONObject(i).put("导入结果", "失败");
                arrayRows.getJSONObject(i).put("备注", "收货仓库为空！");
                continue;
            } else {
                Storehouse storehouse = getStorehouseByName(inboundOrderVo.getStorehouseName());
                if (Objects.isNull(storehouse)) {
                    arrayRows.getJSONObject(i).put("导入结果", "失败");
                    arrayRows.getJSONObject(i).put("备注", "收货仓库不存在！");
                    continue;
                } else {
                    inboundOrderVo.setStorehouseId(storehouse.getId());
                }
            }

            if (StringUtils.isEmpty(inboundOrderVo.getVin())) {
                arrayRows.getJSONObject(i).put("导入结果", "失败");
                arrayRows.getJSONObject(i).put("备注", "车架号为空！");
                continue;
            }

            if (StringUtils.isEmpty(inboundOrderVo.getStrQty())) {
                arrayRows.getJSONObject(i).put("导入结果", "失败");
                arrayRows.getJSONObject(i).put("备注", "数量为空！");
                continue;
            } else {
                try {
                    inboundOrderVo.setQty(Integer.valueOf(inboundOrderVo.getStrQty()));
                } catch (Exception e) {
                    arrayRows.getJSONObject(i).put("导入结果", "失败");
                    arrayRows.getJSONObject(i).put("备注", "数量错误！");
                    continue;
                }
            }

            if (!StringUtils.isEmpty(inboundOrderVo.getExpectArriveDate())) {
                try {
                    inboundOrderVo.setExpectInboundDate(DATE_FORMAT.parse(inboundOrderVo.getExpectArriveDate()));
                } catch (Exception e) {
                    arrayRows.getJSONObject(i).put("导入结果", "失败");
                    arrayRows.getJSONObject(i).put("备注", "预计到达日期转换错误！");
                    continue;
                }
            }

            try {
                saveInboundNotice(inboundOrderVo);
                arrayRows.getJSONObject(i).put("导入结果", "成功");
                arrayRows.getJSONObject(i).put("备注", "");
            } catch (Exception e) {
                arrayRows.getJSONObject(i).put("导入结果", "失败");
                arrayRows.getJSONObject(i).put("备注", e.getMessage());
            }
        }
        map.put("header", arrayHeader);
        map.put("rows", arrayRows);
        return new RestfulResponse<>(0, "导入成功", map);
    }

    private void saveInboundNotice(InboundOrderVo inboundOrderVo) {
        Wrapper<InboundNoticeLine> ew = new EntityWrapper<>();
        ew.eq("owner_id", inboundOrderVo.getCustomer());
        ew.eq("owner_order_no", inboundOrderVo.getOwnerNo());
        ew.eq("lot_no1", inboundOrderVo.getVin());
        ew.ne("status", TableStatusEnum.STATUS_50.getCode());
        if (inboundNoticeLineService.selectCount(ew) > 0) throw new BaseException("订单已导入！");

        InboundNoticeHeader inboundNoticeHeader = new InboundNoticeHeader();
        inboundNoticeHeader.setStoreHouseId(inboundOrderVo.getStorehouseId());
        inboundNoticeHeader.setOwnerId(inboundOrderVo.getCustomer());
        inboundNoticeHeader.setOwnerOrderNo(inboundOrderVo.getOwnerNo());
        inboundNoticeHeader.setExpectSumQty(new BigDecimal(inboundOrderVo.getQty()));
        inboundNoticeHeader.setOrderDate(new Date());
        inboundNoticeHeader.setCarrierName(inboundOrderVo.getCarrierName());
        inboundNoticeHeader.setExpectRecvDateLower(inboundOrderVo.getExpectInboundDate());
        inboundNoticeHeader.setLineCount(1);
        inboundNoticeHeader.setNoticeNo(businessDocNumberService.getInboundNoticeNo());
        inboundNoticeHeader.setStatus(Status.Inbound.NOT);
        inboundNoticeHeader.setPlateNumber(inboundOrderVo.getPlateNumber());
        inboundNoticeHeader.setRemarks("wms_pc手动导入入库头表");

        InboundNoticeLine inboundNoticeLine = new InboundNoticeLine();
        inboundNoticeLine.setOwnerId(inboundOrderVo.getCustomer());
        inboundNoticeLine.setOwnerOrderNo(inboundOrderVo.getOwnerNo());
        inboundNoticeLine.setMaterielId(inboundOrderVo.getVehicleMode());
        inboundNoticeLine.setMaterielName(inboundOrderVo.getVehicleMode());
        inboundNoticeLine.setLotNo1(inboundOrderVo.getVin());
        inboundNoticeLine.setStatus(Status.Inbound.NOT);
        inboundNoticeLine.setUom(MeasureUnit.TAI);
        inboundNoticeLine.setExpectQty(new BigDecimal(inboundOrderVo.getQty()));
        inboundNoticeLine.setDestLocationDetail(inboundOrderVo.getDestLocationDetail());
        inboundNoticeLine.setRemarks("wms_pc手动导入入库明细");
        inboundNoticeHeader.addInboundNoticeLine(inboundNoticeLine);

        if (!inboundNoticeHeaderService.insertInboundNotice(inboundNoticeHeader)) {
            throw new BaseException("导入订单失败");
        }
    }

    private Storehouse getStorehouseByName(String houseName) {
        if (storehouseMap.containsKey(houseName)) {
            return storehouseMap.get(houseName);
        } else {
            Wrapper<Storehouse> ew = new EntityWrapper<>();
            ew.eq("name", houseName);
            Storehouse storehouse = storehouseService.selectOne(ew);
            if (!Objects.isNull(storehouse)) {
                storehouseMap.put(houseName, storehouse);
                return storehouse;
            } else {
                return null;
            }
        }
    }
}
